// 分贝测试器核心功能

document.addEventListener('DOMContentLoaded', function() {
    const startBtn = document.getElementById('startBtn');
    const stopBtn = document.getElementById('stopBtn');
    const decibelValue = document.querySelector('.decibel-value');
    const meterFill = document.getElementById('meterFill');
    const waveformCanvas = document.getElementById('waveformCanvas');
    const intensityValue = document.getElementById('intensityValue');
    
    // 设置canvas上下文
    const ctx = waveformCanvas.getContext('2d');
    // 设置canvas尺寸以适应容器
    function resizeCanvas() {
        const container = waveformCanvas.parentElement;
        waveformCanvas.width = container.clientWidth;
        waveformCanvas.height = container.clientHeight;
    }
    
    // 初始化时调整canvas尺寸
    resizeCanvas();
    // 窗口大小改变时重新调整canvas尺寸
    window.addEventListener('resize', resizeCanvas);
    
    let audioContext;
    let analyser;
    let microphone;
    let dataArray;
    let animationId;
    let isMeasuring = false;
    let mediaStream = null; // 存储音频流引用
    
    // 初始化音频上下文
    function initAudioContext() {
        try {
            audioContext = new (window.AudioContext || window.webkitAudioContext)();
            analyser = audioContext.createAnalyser();
            analyser.fftSize = 256;
            const bufferLength = analyser.frequencyBinCount;
            dataArray = new Uint8Array(bufferLength);
            return true;
        } catch (error) {
            console.error('初始化音频上下文失败:', error);
            alert('您的浏览器不支持Web Audio API，请使用最新的Chrome或Firefox浏览器。');
            return false;
        }
    }
    
    // 获取麦克风权限并开始测量
    async function startMeasurement() {
        try {
            if (!audioContext) {
                if (!initAudioContext()) return;
            }
            
            // 如果音频上下文处于暂停状态，恢复它
            if (audioContext.state === 'suspended') {
                await audioContext.resume();
            }
            
            // 请求用户麦克风权限
            mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });
            microphone = audioContext.createMediaStreamSource(mediaStream);
            microphone.connect(analyser);
            
            isMeasuring = true;
            startBtn.disabled = true;
            stopBtn.disabled = false;
            
            // 开始更新分贝显示
            updateDecibelDisplay();
            
        } catch (error) {
            console.error('获取麦克风权限失败:', error);
            alert('请允许访问您的麦克风以使用分贝测试器。');
            resetMeasurement();
        }
    }
    
    // 停止测量
    function stopMeasurement() {
        if (animationId) {
            cancelAnimationFrame(animationId);
        }
        
        // 停止音频流
        if (mediaStream) {
            mediaStream.getTracks().forEach(track => track.stop());
            mediaStream = null;
        }
        
        resetMeasurement();
    }
    
    // 重置测量状态
    function resetMeasurement() {
        isMeasuring = false;
        startBtn.disabled = false;
        stopBtn.disabled = true;
        decibelValue.textContent = '0';
        decibelValue.style.color = '#2c3e50';
        meterFill.style.width = '0%';
        intensityValue.textContent = '安静';
        intensityValue.className = 'intensity-value quiet';
        
        // 清除历史数据和图表
        dbHistory = [];
        lastRecordTime = 0;
        if (ctx) {
            ctx.clearRect(0, 0, waveformCanvas.width, waveformCanvas.height);
        }
    }
    
    // 更新分贝显示
    function updateDecibelDisplay() {
        if (!isMeasuring) return;
        
        // 获取音频数据
        analyser.getByteFrequencyData(dataArray);
        
        // 计算音频数据的平均值
        let sum = 0;
        for (let i = 0; i < dataArray.length; i++) {
            sum += dataArray[i];
        }
        const average = sum / dataArray.length;
        
        // 将音频数据转换为分贝值（更准确的映射）
        // 使用更合适的系数，使读数更符合实际环境
        const db = Math.round(average * 0.4); // 降低系数以获得更准确的读数
        
        // 更新显示
        decibelValue.textContent = db;
        
        // 根据分贝值改变颜色
        if (db < 30) {
            decibelValue.style.color = '#4caf50'; // 绿色
        } else if (db < 60) {
            decibelValue.style.color = '#ff9800'; // 橙色
        } else if (db < 90) {
            decibelValue.style.color = '#f44336'; // 红色
        } else {
            decibelValue.style.color = '#9c27b0'; // 紫色
        }
        
        // 更新进度条
        const percentage = Math.min(db * 0.83, 100); // 限制最大值为100%
        meterFill.style.width = `${percentage}%`;
        
        // 更新声音强度指示器
        updateIntensityIndicator(db);
        
        // 绘制时间序列图表
        drawTimeSeriesChart(db);
        
        // 继续下一帧更新
        animationId = requestAnimationFrame(updateDecibelDisplay);
    }
    
    // 更新声音强度指示器
    function updateIntensityIndicator(db) {
        // 移除所有强度类
        intensityValue.className = 'intensity-value';
        
        // 根据分贝值设置强度文本和样式
        if (db < 30) {
            intensityValue.textContent = '安静';
            intensityValue.classList.add('quiet');
        } else if (db < 60) {
            intensityValue.textContent = '中等';
            intensityValue.classList.add('moderate');
        } else if (db < 90) {
            intensityValue.textContent = '吵闹';
            intensityValue.classList.add('loud');
        } else {
            intensityValue.textContent = '危险';
            intensityValue.classList.add('dangerous');
        }
    }
    
    // 存储历史分贝数据
    let dbHistory = [];
    const maxHistoryPoints = 30; // 最多显示30个点（30秒）
    let lastRecordTime = 0;
    
    // 绘制时间序列图表（每秒记录一次）
    function drawTimeSeriesChart(db) {
        const now = Date.now();
        
        // 每秒记录一次数据
        if (now - lastRecordTime >= 1000) {
            // 添加新的分贝值到历史数据
            dbHistory.push(db);
            
            // 如果数据点过多，移除最早的数据
            if (dbHistory.length > maxHistoryPoints) {
                dbHistory.shift();
            }
            
            lastRecordTime = now;
        }
        
        const width = waveformCanvas.width;
        const height = waveformCanvas.height;
        
        // 清除画布
        ctx.clearRect(0, 0, width, height);
        
        if (dbHistory.length === 0) return;
        
        // 设置图表样式
        ctx.lineWidth = 2;
        ctx.strokeStyle = '#3498db';
        ctx.fillStyle = 'rgba(52, 152, 219, 0.1)';
        
        // 计算比例
        const padding = 20;
        const chartWidth = width - padding * 2;
        const chartHeight = height - padding * 2;
        const xStep = chartWidth / (maxHistoryPoints - 1);
        
        // 找出历史数据中的最大值，用于缩放Y轴
        const maxDb = Math.max(...dbHistory, 100); // 至少100dB作为参考
        
        // 绘制背景网格
        ctx.strokeStyle = '#e0e0e0';
        ctx.lineWidth = 1;
        
        // 水平线（每20dB一条）
        ctx.beginPath();
        for (let i = 0; i <= 5; i++) {
            const y = height - padding - (i * 20 / maxDb) * chartHeight;
            ctx.moveTo(padding, y);
            ctx.lineTo(width - padding, y);
        }
        ctx.stroke();
        
        // 垂直线（每5秒一条）
        ctx.beginPath();
        for (let i = 0; i <= maxHistoryPoints; i += 5) {
            const x = padding + (i / (maxHistoryPoints - 1)) * chartWidth;
            ctx.moveTo(x, padding);
            ctx.lineTo(x, height - padding);
        }
        ctx.stroke();
        
        // 绘制数据点和连接线
        ctx.strokeStyle = '#3498db';
        ctx.fillStyle = '#3498db';
        ctx.lineWidth = 2;
        
        ctx.beginPath();
        
        for (let i = 0; i < dbHistory.length; i++) {
            const x = padding + (i / (maxHistoryPoints - 1)) * chartWidth;
            const y = height - padding - (dbHistory[i] / maxDb) * chartHeight;
            
            // 确保y值在有效范围内
            const clampedY = Math.max(padding, Math.min(height - padding, y));
            
            if (i === 0) {
                ctx.moveTo(x, clampedY);
            } else {
                ctx.lineTo(x, clampedY);
            }
        }
        
        ctx.stroke();
        
        // 绘制数据点和对应的数值标签
        ctx.fillStyle = '#3498db';
        for (let i = 0; i < dbHistory.length; i++) {
            const x = padding + (i / (maxHistoryPoints - 1)) * chartWidth;
            const y = height - padding - (dbHistory[i] / maxDb) * chartHeight;
            
            // 确保y值在有效范围内
            const clampedY = Math.max(padding, Math.min(height - padding, y));
            
            // 绘制数据点
            ctx.beginPath();
            ctx.arc(x, clampedY, 3, 0, 2 * Math.PI);
            ctx.fill();
            
            // 绘制分贝数值标签
            ctx.fillStyle = '#2c3e50';
            ctx.font = '11px Arial';
            ctx.textAlign = 'center';
            ctx.fillText(`${dbHistory[i]}`, x, clampedY - 10);
            ctx.fillStyle = '#3498db'; // 恢复数据点的填充颜色
        }
    }
    
    // 添加按钮事件监听
    startBtn.addEventListener('click', startMeasurement);
    stopBtn.addEventListener('click', stopMeasurement);
    
    // 页面卸载时清理资源
    window.addEventListener('beforeunload', function() {
        stopMeasurement();
        if (audioContext) {
            audioContext.close();
        }
    });
    
    console.log('分贝测试器已加载');
});